package de.koller.worlders.render;

import de.koller.oceanFramework.math.Vec;
import de.koller.worlders.WSea;
import de.koller.worlders.WorldersRoot;
import de.koller.worlders.engine.tiles.TileMap;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class WRendering extends WSea {

	public static final float SCALE = 32;
	public static final int TEXTURE_SIZE = (int)SCALE;
	public static float SCREEN_MID_X;
	public static float SCREEN_MID_Y;	
	private boolean cameraSet = false;
	private final Vec cameraMid = new Vec();
	
	private TileMap map;
	
	@Override
	protected void init() {
		super.init();
	
		SCREEN_MID_X = WorldersRoot.D_WIDTH / 2f / SCALE;
		SCREEN_MID_Y = WorldersRoot.D_HEIGHT / 2f / SCALE;
		map = wroot.getTileMap();
	}

	@Override
	protected void update( int elapsedTime ) {
		super.update( elapsedTime );
		
		cameraMid.setX( -wroot.getTileMap().getOffsetX() + 12 );
		cameraMid.setY( -wroot.getTileMap().getOffsetY() +  9 );
	}
	
	public void setTransform() {
		assert !cameraSet;
		
		cameraSet = true;
		GL11.glPushMatrix();
		
		GL11.glTranslatef( WorldersRoot.D_WIDTH * .5f, WorldersRoot.D_HEIGHT * .5f, 0 );
		GL11.glRotatef( wroot.rendering.getgRota(), 0, 0, 1 );
		GL11.glScalef( wroot.rendering.getgZoom(), wroot.rendering.getgZoom(), 1 );
		GL11.glTranslatef( -WorldersRoot.D_WIDTH * .5f, -WorldersRoot.D_HEIGHT * .5f, 0 );
		
		GL11.glScalef( SCALE, SCALE, 1 );
		GL11.glTranslatef( map.getOffsetX(), map.getOffsetY(), 0 );
	}
	
	public void unsetTransform() {
		assert cameraSet;
		
		GL11.glPopMatrix();
		cameraSet = false;
	}
	
	public boolean isCameraSet() {
		return cameraSet;
	}
	
//	public void renderAABB( AABBObject r, float z ) {
//		renderAABB( r, z, 0 );
//	}
//	
//	public void renderAABB( AABBObject r, float z, float rotation ) {
//		//@todo check if aabb is outside the screen
//		float tw = r.getSize().getXf();// * SCALE;
//		float th = r.getSize().getYf();// * SCALE;
//		float tx = r.getPosition().getXf();
//		float ty = r.getPosition().getYf();
//		renderAABB( r, tx, ty, tw, th, z, rotation );
//	}
//	
//	public void renderAABB( AABBObject r, float tx, float ty, float tw, float th, float z, float rotation ) {
//		if( r.getTexture() == null ) {
//			if( r.getTextureRep() == null )
//				r.setTextureRep( new TextureRep( r.getColor() ) );
//			
//			r.setTexture( r.getTextureRep().generate( wroot.getBuffers() ) );
//		}
//		
//		IRenderableImage img = r.getTexture();
////		byte[] c = ColorIntUtil.getRGBA( r.getLight().getLight() );
//		byte[] c = ColorIntUtil.getRGBA( r.getTextureColor() );
//		
//		if( rotation != 0 ) {
//			GL11.glPushMatrix();
//			GL11.glTranslatef( tx + tw*.5f, ty + th*.5f, 0 );
//			GL11.glRotatef( rotation, 0, 0, 1 );
//			GL11.glTranslatef( -tx - tw*.5f, -ty - th*.5f, 0 );
//		}
//		GL11.glColor4ub( c[0], c[1], c[2], c[3] );
//		
//		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
//		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP );
//		
//		if( r.getTextureRep() == null )
//			img.draw2D( tx, ty, tw, th, z, 0, 0, img.getU(), img.getV() );
//		
//		if( r.getTextureRep() != null ) {
//			TextureRep t = r.getTextureRep();
//			float u0 =  r.isMirrorX() ? img.getU() : 0;
//			float u1 = !r.isMirrorX() ? img.getU() : 0;
//			float v0 =  r.isMirrorY() ? img.getV() : 0;
//			float v1 = !r.isMirrorY() ? img.getV() : 0;
//			
//			img.draw2D( tx, ty, tw, th, z, u0, v0, u1, v1 );
//		}
//		
//		if( rotation != 0 )
//			GL11.glPopMatrix();
//	}
	
	public Vec getWorldPosition( int screenX, int screenY ) {		
		assert cameraSet;
		
		IntBuffer viewport = BufferUtils.createIntBuffer( 16 );
		FloatBuffer modelview = BufferUtils.createFloatBuffer( 16 );
		FloatBuffer projection = BufferUtils.createFloatBuffer( 16 );

		float winX, winY;
		FloatBuffer pos = BufferUtils.createFloatBuffer( 3 );
		
		GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, modelview );
		GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, projection );
		GL11.glGetInteger( GL11.GL_VIEWPORT, viewport );
		
		winX = (float)screenX;
		winY = (float)viewport.get( 3 ) - (float)screenY;

		GLU.gluUnProject( winX, winY, 0, modelview, projection, viewport, pos );
		return new Vec( pos.get( 0 ), pos.get( 1 ) );
	}
	
	public Vec getCameraMid() {
		return cameraMid;
	}
	
}
